﻿using System;
using WorkLogger.Client.Commands;
using WorkLogger.Client.DataAccess.Model;
using WorkLogger.Client.Forms;

namespace WorkLogger.Client.Presenters {
	public class MainFormPresenter {
		private readonly IMainForm mainForm;
		private readonly IWorkDayManager workDayManager;
		private readonly WorkTimeCalculator workTimeCalculator;
		private readonly LunchTimePresenter lunchTimePresenter;
		private readonly AppOptions appOptions;
		private readonly ICommandFactory commandFactory;

		public MainFormPresenter(IMainForm mainForm,
		                         IWorkDayManager workDayManager,
		                         WorkTimeCalculator workTimeCalculator,
		                         AppOptions appOptions,
		                         ICommandFactory commandFactory,
		                         LunchTimePresenter lunchTimePresenter,
		                         MainMenuPresenter mainMenuPresenter) {
			this.mainForm = mainForm;
			this.workDayManager = workDayManager;
			this.workTimeCalculator = workTimeCalculator;
			this.appOptions = appOptions;
			this.commandFactory = commandFactory;
			this.mainForm.Shown += MainFormShown;
			this.lunchTimePresenter = lunchTimePresenter;
			lunchTimePresenter.LunchChanged += LunchTimePresenterLunchChanged;
			mainMenuPresenter.OptionsChanged += MainMenuPresenterOptionsChanged;
		}

		private void MainMenuPresenterOptionsChanged(object sender, EventArgs e) {
			UpdateForm();
		}

		private void LunchTimePresenterLunchChanged(object sender, EventArgs e) {
			UpdateForm();
		}

		private void MainFormStartWorkingChanged(object sender, EventArgs e) {
			workDayManager.GetCurrentWorkDay().StartWork = mainForm.StartWorking;
			workDayManager.Update();
			UpdateForm();
		}

		private void MainFormTick(object sender, EventArgs e) {
			ExecuteAction(commandFactory.CreateTickCommand());
		}

		private void MainFormShown(object sender, EventArgs e) {
			ExecuteAction(commandFactory.CreateResumeWorkingCommand());
			mainForm.Tick += MainFormTick;
			mainForm.StartWorkingChanged += MainFormStartWorkingChanged;
		}

		private void ExecuteAction(ICommand command) {
			command.Execute();
			UpdateForm();
		}

		private void UpdateForm() {
			WorkDay currentWorkDay = workDayManager.GetCurrentWorkDay();

			TimeSpan workedTime = workTimeCalculator.GetWorkedTime(currentWorkDay);
			TimeSpan workDayDuration = appOptions.WorkDayDuration.GetTimeSpan();
			mainForm.SetWorkedTime(workedTime, workDayDuration);
			mainForm.CurrentDate = currentWorkDay.WorkDate;
			mainForm.StartWorking = currentWorkDay.StartWork;
			lunchTimePresenter.Update();
		}

		public void SessionLock(DateTime beginLocking) {
			mainForm.Tick -= MainFormTick;
		}

		public void SessionUnlock(DateTime endLocking) {
			ExecuteAction(commandFactory.CreateResumeWorkingCommand());
			mainForm.Tick += MainFormTick;
		}
	}
}